import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:kq_flutter_core_widget/extentions/kq_extentions.dart';
import 'package:kq_flutter_core_widget/widgets/expandablePageView/kq_size_reporting_widget.dart';
import 'package:kq_flutter_core_widget/widgets/gesture/kq_gesture_detector.dart';

/// 悬浮控件
class KqFloatingView extends StatefulWidget {
  /// [floatingWidget] 将悬浮在 [child] 之上
  final Widget child;

  /// 悬浮控件
  final Widget Function(
          double? left, double? top, bool isLeft, bool isDragging)?
      floatingWidgetBuilder;

  /// 初始位置-left
  final double? left;

  /// 初始位置-top
  final double? top;

  /// 是否可拖拽,默认true
  final bool dragAble;

  /// 是否松手后自动贴边吸附，默认true
  final bool autoSide;

  const KqFloatingView(
      {Key? key,
      required this.child,
      this.left,
      this.top,
      this.floatingWidgetBuilder,
      this.autoSide = true,
      this.dragAble = true})
      : super(key: key);

  @override
  KqFloatingViewState createState() => KqFloatingViewState();
}

class KqFloatingViewState extends State<KqFloatingView>
    with SingleTickerProviderStateMixin {
  double? left;
  double? top;

  Offset? startPos;

  Size? floatingSize;

  bool releaseIsLeft = true;
  double? releaseX;

  bool isDragging = false;

  late AnimationController _controller;

  static const Duration _sideDuration = Duration(milliseconds: 150);

  @override
  void initState() {
    left = widget.left ?? 0;
    top = widget.top;
    _controller = AnimationController(duration: _sideDuration, vsync: this)
      ..value = 0
      ..addListener(() {
        if (widget.autoSide) {
          setState(() {
            var value = _controller.value;
            if (releaseIsLeft) {
              // 左移
              left = (1 - value) * left!;
            } else {
              // 右移
              if (floatingSize != null && releaseX != null) {
                // 不能超出屏幕
                var maxLeft = context.width - floatingSize!.width;
                var l = value * maxLeft;
                if (l > releaseX!) {
                  left = l;
                } else if (releaseX! > maxLeft) {
                  left = maxLeft;
                }
              }
            }
          });
        }
      });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var parentPos = context.position();
    var width = context.width;
    return LayoutBuilder(
      builder: (ctx, constraintType) {
        var height = constraintType.maxHeight;
        var isLeft =
            ((left ?? 0) + ((floatingSize?.width ?? 0) / 2)) < width / 2;
        Widget child = KqSizeReportingWidget(
          onSizeChange: (Size? value) {
            setState(() {
              floatingSize = value;
            });
          },
          child: widget.floatingWidgetBuilder == null
              ? Container()
              : widget.floatingWidgetBuilder!
                  .call(left, top, isLeft, isDragging),
        );
        if (widget.dragAble) {
          child = KqGestureDetector(
            onDragStart: (details) {
              startPos = details.localPosition;
            },
            onDragEnd: (details) {
              //自动吸附
              isDragging = false;
              if (widget.autoSide) {
                _controller.forward(from: 0);
              }
              releaseIsLeft =
                  ((left ?? 0) + ((floatingSize?.width ?? 0) / 2)) < width / 2;
              releaseX = left;
              // 位置校准
            },
            onDragUpdate: (details) {
              isDragging = true;
              var globalPos = details.globalPosition;
              var dx = globalPos.dx - startPos!.dx;
              var dy = globalPos.dy - startPos!.dy - (parentPos?.dy ?? 0);
              if (dx < 0) {
                dx = 0;
              }
              if (dy < 0) {
                dy = 0;
              }
              if (floatingSize != null) {
                // 不能超出屏幕
                if (dx > (width - floatingSize!.width)) {
                  dx = width - floatingSize!.width;
                }
                if (dy > (height - floatingSize!.height)) {
                  dy = height - floatingSize!.height;
                }
              }
              setState(() {
                left = dx;
                top = dy;
              });
            },
            onDragCancel: () {
              isDragging = false;
              startPos = null;
            },
            child: child,
          );
        }
        return Stack(
          children: [
            widget.child,
            if (widget.floatingWidgetBuilder != null)
              Positioned(left: left, top: top ?? height / 2, child: child),
          ],
        );
      },
    );
  }
}
